package b.sync.utils

import scala.reflect.macros.whitebox

object Macros {
  def extract[T: c.WeakTypeTag](c: whitebox.Context): c.Tree = {
    import c.universe._
    val t: c.WeakTypeTag[T] = implicitly[c.WeakTypeTag[T]]
    q"""
      import b.sync.domain._
      val x = Generic[$t]
      type ReadRepr = x.Repr :: Int :: Int :: HNil
      val rows = stmtQuery.retrieve[ReadRepr](from).on(ds)
      rows.map( xRows => xRows.map { r =>
        (x.from(r.head), r.tail.head, r.tail.tail.head)
      })
     """
  }
  def replicate[T: c.WeakTypeTag, K: c.WeakTypeTag](c: whitebox.Context): c.Tree = {
    import c.universe._
    val t: c.WeakTypeTag[T] = implicitly[c.WeakTypeTag[T]]
    val k: c.WeakTypeTag[K] = implicitly[c.WeakTypeTag[K]]
    q"""
       import b.sync.domain._
       def forUpdate(a: $t) = Generic[$t].to(a) :+ Generic[$k].to(uniqueKeyOf(a))
       val (opType, rows) = rowsGroup
       opType match {
         case 1 => stmtInsert.execute(rows.map(_._1)                 ).on(ds)
         case 2 => stmtUpdate.execute(rows.map(_._1).map(forUpdate)  ).on(ds)
         case 3 => stmtDelete.execute(rows.map(_._1).map(uniqueKeyOf)).on(ds)
         case _ => effect.IO(0)
       }
     """
  }
}
